// https://brennan.io/2015/01/16/write-a-shell-in-c/
// https://medium.com/@santiagobedoa/coding-a-shell-using-c-1ea939f10e7e

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shell.h"

#define MAX_INPUT_SIZE 1024

// Function to initialize the shell
void initialize_shell(void)
{
    // You can perform any necessary initialization here.
    // For example, initializing data structures, setting signal handlers, etc.
}

// Function to parse and execute user commands

char *read_line(void)
{
    char *line = NULL;
    // ssize or size_t?
    size_t buf = 0; // have getline allocate a buffer for us

    if (getline(&line, &buf, stdin) == -1)
    {
        if (feof(stdin))
        {
            exit(EXIT_SUCCESS); // EOF ^D
        }
        else
        {
            perror("readline");
            exit(EXIT_FAILURE);
        }
    }
    return line;
}

char **parse_line(char *input, int *argc)
{
    int bufsize = 64; // Initial buffer size
    char **tokens = (char **)malloc(bufsize * sizeof(char *));
    if (!tokens)
    {
        // fprintf(stderr, "Memory allocation error\n");
        exit(EXIT_FAILURE);
    }

    char *token;
    int position = 0;

    token = strtok(input, " \t\r\n\a");
    while (token != NULL)
    {
        // printf("Token: %s\n", token);
        tokens[position] = token;
        position++;

        if (position >= bufsize)
        {
            bufsize += 64; // Increase buffer size if necessary
            tokens = (char **)realloc(tokens, bufsize * sizeof(char *));
            if (!tokens)
            {
                fprintf(stderr, "Memory allocation error\n");
                exit(EXIT_FAILURE);
            }
        }

        token = strtok(NULL, " \t\r\n\a");
    }

    tokens[position] = NULL; // Null-terminate the array
    *argc = position;

    return tokens;
}

// Function for the main loop of the shell
void shell(void)
{
    char *line = NULL;
    int argc = 0;
    char **args = NULL;
    int status = 0;

    do
    {
        print_prompt();
        line = read_line();
        args = parse_line(line, &argc);
        status = execute_command(argc, args);

        free(line);
        free(args);
    } while (status != -1);

    return;
}

// Function to clean up and exit the shell
void cleanup_shell(void)
{
    // You can perform cleanup tasks here, such as freeing resources, closing files, etc.
}
